home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 19 code / SimpliFace_V2 / Sources / SimpliFace2.cp < prev    next >
Encoding:
Text File  |  1994-05-01  |  25.2 KB  |  1,071 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        SimpliFace2.cp
  3.  
  4.     Contains:    A simple scriptable application class.
  5.  
  6.  
  7.     Developed by:
  8.  
  9.     Paul G Smith (commstalk hq & Full Moon Software, Inc)
  10.  
  11.     you can leave messages at (UK): 0727 844232; (US): 408 253 7199
  12.     BUT I prefer to be contacted by e-mail
  13.     AppleLink:     COMMSTALK.HQ
  14.     Internet:     COMMSTALK.HQ@applelink.apple.com
  15.  
  16.     "SimpliFace2" Sample code to accompany develop article
  17.     on techniques for controlling script inheritance.
  18.     
  19.     
  20.  
  21.  
  22. */
  23.  
  24.  
  25. #ifndef __SimpliFace2__
  26. #include <SimpliFace2.h>
  27. #endif
  28.  
  29. #ifndef __SimpliFace2COMMON__
  30. #include "SimpliFace2Common.h"
  31. #endif
  32.  
  33. #ifndef __APPLICATIONCOMMON__
  34. #include "ApplicationCommon.h"
  35. #endif
  36.  
  37. #ifndef __STDIO__
  38. #include <StdIO.h>
  39. #endif
  40.  
  41. #ifndef __GESTALTEQU__
  42. #include <GestaltEqu.h>
  43. #endif
  44. #ifndef __MENUS__
  45. #include <Menus.h>
  46. #endif
  47. #ifndef __FONTS__
  48. #include <Fonts.h>
  49. #endif
  50. #ifndef __EVENTS__
  51. #include <Events.h>
  52. #endif
  53. #ifndef __WINDOWS__
  54. #include <Windows.h>
  55. #endif
  56. #ifndef __DIALOGS__
  57. #include <Dialogs.h>
  58. #endif
  59. #ifndef __QUICKDRAW__
  60. #include <Quickdraw.h>
  61. #endif
  62. #ifndef __MEMORY__
  63. #include <Memory.h>
  64. #endif
  65. #ifndef __RESOURCES__
  66. #include <Resources.h>
  67. #endif
  68. #ifndef __PACKAGES__
  69. #include <Packages.h>
  70. #endif
  71. #ifndef __TOOLUTILS__
  72. #include <ToolUtils.h>
  73. #endif
  74. #ifndef __FILES__
  75. #include <Files.h>
  76. #endif
  77. #ifndef __STANDARDFILE__
  78. #include <StandardFile.h>
  79. #endif
  80. #ifndef __SYSEQU__
  81. #include <SysEqu.h>
  82. #endif
  83. #ifndef __PLSTRINGFUNCS__
  84. #include <PLStringFuncs.h>
  85. #endif
  86.  
  87. #ifndef __AEOBJECTS__
  88. #include <AEObjects.h>
  89. #endif
  90.  
  91. #ifndef __AEOBJECTPACKING__
  92. #include <AEPackObject.h>
  93. #endif
  94.  
  95. #ifndef __AERegistry__
  96. #include <AERegistry.h>
  97. #endif
  98. #ifndef __ASREGISTRY__
  99. #include <ASRegistry.h>
  100. #endif
  101.  
  102. #ifndef __AEOMTOKENS__
  103. #include "ObjModelTokens.h"
  104. #endif
  105. #ifndef __AEOMEVENTS__
  106. #include "ObjModelEvents.h"
  107. #endif
  108.  
  109. #ifndef __SCRIPTUTILS__
  110. #include "ScriptUtils.h"
  111. #endif
  112.  
  113. #ifndef __WINDOWOBJ__
  114. #include "WindowObj.h"
  115. #endif
  116.  
  117. extern "C" {
  118. #include "AEBuild.h"
  119. #include "AEBuildGlobals.h"
  120. #include "AEPrint.h"
  121. }
  122. #include "AEBuildErrMsgs.h"
  123.  
  124.  
  125. #include "DebugTrace.h"
  126.  
  127.  
  128. #define        kMinStackSize     40000
  129. #define        kMinHeapSize     150000
  130.  
  131. #define        kWNEsleepTicks    10
  132.  
  133. #define     kSaveGlobVars    false
  134.  
  135.  
  136. /* some globals we need for the static methods */
  137.  
  138. TSimpliFace2*    gSimpliFace2 = NULL;
  139. Boolean         gDone = false;
  140. Boolean         gQuit = false;
  141.  
  142. int main()
  143. {
  144.     InstallWriteLnHook();    // debug assistance, so printf() works for us
  145.     ForceDebug();
  146.     
  147.     gSimpliFace2 = new TSimpliFace2(Ptr(&qd));
  148.     
  149.     AEObjectInit();
  150.  
  151.     // Start our main event loop running.
  152.     while (!gQuit && gSimpliFace2) 
  153.     {
  154.         gSimpliFace2->EventLoop();
  155.         gQuit = true;
  156.     }
  157.     if (gSimpliFace2)
  158.     {
  159.         delete gSimpliFace2;
  160.         gSimpliFace2 = NULL;
  161.     }
  162.     
  163.     // We always return a value, like good little ANSI worshippers
  164.     return 0;
  165. }
  166.  
  167. /**********************************************************************
  168. **  SimpliFace2 static methods
  169. ***********************************************************************/
  170.  
  171. #define optionKeyCode     58
  172. static Boolean isKeyDown(long keyCode);
  173. static void AlertUser(short errResID, short errCode);
  174.  
  175. /**********************************************************************
  176. ** isKeyDown
  177. ***********************************************************************/
  178.  
  179. static Boolean isKeyDown(long keyCode)
  180. {
  181.     KeyMap keys;
  182.     Byte *keysBytes;
  183.     
  184.     GetKeys(keys);
  185.     
  186.     keysBytes = (Byte *)keys;
  187.  
  188.     return((keysBytes[keyCode/8] & (1 << keyCode % 8)) != 0);
  189. }
  190.  
  191. /**********************************************************************
  192. **  AlertUser
  193. ***********************************************************************/
  194.  
  195. void AlertUser(short errResID, short errCode)
  196. {
  197.     Str255 message;
  198.  
  199.     GetIndString(message, errResID, errCode);
  200.     #if qDebug
  201.     if (message[0] == 0)
  202.     {
  203.         DebugStr((ConstStr255Param)"\pProgram error: could not get error string.");
  204.         return;
  205.     }
  206.     #endif
  207.     ParamText(message, (ConstStr255Param)"\p", (ConstStr255Param)"\p", (ConstStr255Param)"\p");
  208.     Alert(rUserAlert, NULL);
  209. }
  210.  
  211. /**********************************************************************
  212. **  CheckGestaltOSA: return false if we can't load
  213. ***********************************************************************/
  214.  
  215. Boolean CheckGestaltOSA(void)
  216. {
  217.     OSErr    err = 0;
  218.     long    ascrAttr = 0;
  219.     long    ascrVers = 0;
  220.     char    ascrVersStr[24];
  221.     
  222.     err = Gestalt('ascr', &ascrAttr);
  223.     if (err == noErr)
  224.     {
  225.         err = Gestalt('ascv', &ascrVers);
  226.         sprintf(ascrVersStr, "%.8lx", ascrVers);
  227.         printf("AppleScript version %.2s.%.1s.%.1s   [$%s]\n", 
  228.                 &ascrVersStr[0], &ascrVersStr[2], &ascrVersStr[3], ascrVersStr);
  229.     }
  230.     else
  231.         printf("AppleScript not present\n");
  232.     
  233.     return (err == 0);
  234. }
  235.  
  236. /**********************************************************************
  237. ** PUBLIC Constructor
  238. ***********************************************************************/
  239.  
  240. TSimpliFace2::TSimpliFace2(Ptr qdPtr) : TApplication(qdPtr)
  241. {    
  242.     if (CheckGestaltOSA())
  243.     {
  244.         // read menus into menu bar
  245.     
  246.         Handle menuBar = GetNewMBar(rMenuBar);
  247.         // install menus
  248.         SetMenuBar(menuBar);
  249.     
  250.         // add DA names to Apple menu
  251.         AddResMenu(GetMHandle(mApple),'DRVR');
  252.         DrawMenuBar();
  253.     
  254.         // create empty mouse region
  255.         fMouseRgn = NewRgn();
  256.         // make sure we have a valid cursor region
  257.         AdjustCursor();
  258.     }
  259.     else
  260.         TApplication::BigBadError(kApplicationErrStrings,eNeedAS); // if not, alert & quit
  261. }
  262.  
  263. TSimpliFace2::~TSimpliFace2()
  264. {
  265.     StopScriptAdministrator(false);    // in case this is a forced exit, don't save globals
  266.     DisposHandle(Handle(fMouseRgn));
  267. }
  268.  
  269. /**********************************************************************
  270. ** PUBLIC SetUp/Cleanup
  271. ***********************************************************************/
  272.  
  273. void TSimpliFace2::SetUp()
  274. {    // Run before event loop starts
  275.     OSAError         err = 0;
  276.     
  277.     err = StartScriptAdministrator();
  278.     if (err == noErr && gScriptAdministrator)
  279.         SetCurParent(NULL);
  280. }
  281.  
  282. void TSimpliFace2::CleanUp()
  283. {
  284.     StopScriptAdministrator(kSaveGlobVars);    // set to true to save global vars on exit
  285. }
  286.  
  287. /**********************************************************************
  288. ** PUBLIC SleepVal
  289. ***********************************************************************/
  290.  
  291. unsigned long TSimpliFace2::SleepVal()
  292. {
  293.     return kWNEsleepTicks;        // how long to sleep in WaitNextEvent
  294. }
  295.  
  296.  
  297. /**********************************************************************
  298. ** PUBLIC DoIdle
  299. ***********************************************************************/
  300.  
  301. void TSimpliFace2::DoIdle()
  302. {
  303. }
  304.  
  305.  
  306. Boolean TSimpliFace2::HandleGoAway (AEDesc *target, WindowPtr tWind)
  307. {
  308.     Boolean                wasHandled = false;
  309.     OSErr                err = 0;
  310.     AppleEvent            event, reply;
  311.     ProcessSerialNumber    aSelfPSN = gSelfPSN;
  312.     CStr255                aeOtherParams =    "'savo':'ask '";
  313.     
  314.     err = AEBuildAppleEvent(kAECoreSuite, kAEClose,
  315.                             typeProcessSerialNumber, &aSelfPSN,
  316.                             sizeof(aSelfPSN), kAutoGenerateReturnID,
  317.                             kAnyTransactionID, &event,
  318.                             (char*)aeOtherParams);
  319.     if (err == noErr)
  320.         err = AEPutParamDesc(&event, keyDirectObject, target);
  321.     
  322.     if (err == noErr)
  323.     {
  324.         err = AESend(&event, &reply, kAENoReply+kAEAlwaysInteract, 
  325.                          kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
  326.         AEDisposeDesc(&event);
  327.         wasHandled = (err == noErr);
  328.     }
  329.     
  330.     return wasHandled;
  331. }
  332.  
  333.  
  334. Boolean TSimpliFace2::HandleContentClick (AEDesc *target, 
  335.                                          WindowPtr tWind, EventRecord& theEvent)
  336. {
  337.     Boolean                wasHandled = false;
  338.     Point                clickPt = theEvent.where;
  339.     ControlHandle        whichControl = NULL;
  340.     
  341.     GlobalToLocal(&clickPt);
  342.     
  343.     short controlPart = FindControl(clickPt, tWind, &whichControl);
  344.     
  345.     if (!controlPart || 
  346.         (controlPart && whichControl && TrackControl(whichControl, clickPt, NULL)))
  347.     {
  348.         OSErr                err = 0;
  349.         AppleEvent            event, reply;
  350.         ProcessSerialNumber    aSelfPSN = gSelfPSN;
  351.         CStr255                theHPos, theVPos;
  352.         NumToString(theEvent.where.h, theHPos);
  353.         NumToString(theEvent.where.v, theVPos);
  354.         CStr255                aeOtherParams =    "'PEVK':'EMOU',"
  355.                                             "'data':[“" + theHPos + "”,"
  356.                                                     "“" + theVPos + "”]";
  357.         err = AEBuildAppleEvent(kSignature, kAESystemEvent,
  358.                                 typeProcessSerialNumber, &aSelfPSN,
  359.                                 sizeof(aSelfPSN), kAutoGenerateReturnID,
  360.                                 kAnyTransactionID, &event,
  361.                                 (char*)aeOtherParams);
  362.         if (err == noErr)
  363.             err = AEPutParamDesc(&event, keyDirectObject, target);
  364.         
  365.         if (err == noErr)
  366.         {
  367.             err = AESend(&event, &reply, kAENoReply+kAEAlwaysInteract, 
  368.                              kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
  369.             AEDisposeDesc(&event);
  370.             wasHandled = (err == noErr);
  371.         }
  372.     }
  373.     return wasHandled;
  374. }
  375.  
  376.  
  377. Boolean TSimpliFace2::HandleMenuCommand(AEDesc *target, 
  378.                                         short menuNum, short itemNum)
  379. {
  380.     Boolean            wasHandled = false;
  381.     MenuHandle        thisMenu = GetMHandle(menuNum);
  382.     CStr255            menuName, itemName;
  383.     
  384.     if (thisMenu && *thisMenu)
  385.     {
  386.         GetItem(thisMenu, itemNum, itemName);
  387.         menuName = ((*thisMenu)->menuData);
  388.     }
  389.     else
  390.     {
  391.         menuName = "";
  392.         itemName = "";
  393.     }
  394.     
  395.     if (menuName != "" && itemName != "")
  396.     {
  397.         OSErr                err = 0;
  398.         AppleEvent            event, reply;
  399.         ProcessSerialNumber    aSelfPSN = gSelfPSN;
  400.         CStr255                aeOtherParams =    "'PEVK':'EMEN',"
  401.                                             "'data':[“" + menuName + "”,"
  402.                                                     "“" + itemName + "”]";
  403.         err = AEBuildAppleEvent(kSignature, kAESystemEvent,
  404.                                 typeProcessSerialNumber, &aSelfPSN,
  405.                                 sizeof(aSelfPSN), kAutoGenerateReturnID,
  406.                                 kAnyTransactionID, &event,
  407.                                 (char*)aeOtherParams);
  408.         if (err == noErr)
  409.             err = AEPutParamDesc(&event, keyDirectObject, target);
  410.         
  411.         if (err == noErr)
  412.         {
  413.             err = AESend(&event, &reply, kAENoReply+kAEAlwaysInteract, 
  414.                              kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
  415.             AEDisposeDesc(&event);
  416.             wasHandled = (err == noErr);
  417.         }
  418.     }
  419.     return wasHandled;
  420. }
  421.  
  422.  
  423. Boolean TSimpliFace2::HandleMouseDown(AEDesc *target, EventRecord& theEvent)
  424. {
  425.     Boolean        wasHandled = false;
  426.     long         mResult;
  427.     short         partCode;
  428.     WindowPtr     tWind;
  429.  
  430.     // gotta watch those object Label dereferences
  431.     partCode = FindWindow(theEvent.where, &tWind);
  432.     switch (partCode)
  433.       {
  434.         case inMenuBar :
  435.             AdjustMenus();
  436.             mResult = MenuSelect(theEvent.where);
  437.             if (mResult != 0)
  438.             {
  439.                 wasHandled = HandleMenuCommand(target, HiWord(mResult), LoWord(mResult));
  440.                 if (!wasHandled)    // hack! we are anticipating EventLoop():
  441.                 {                    // this is to avoid calling MenuSelect() twice
  442.                     DoMenuCommand(HiWord(mResult),LoWord(mResult));
  443.                     wasHandled = true;    
  444.                 }
  445.             }
  446.             break;
  447.         case inGoAway :
  448.             wasHandled = HandleGoAway(target, tWind);                    
  449.             break;
  450.         case inContent :
  451.             // If window is not in front, make it so
  452.             if ( tWind != FrontWindow() )
  453.                   SelectWindow(fWhichWindow);
  454.             else
  455.                 wasHandled = HandleContentClick(target, tWind, theEvent);                    
  456.             break;
  457.       }    
  458.     
  459.     return wasHandled;
  460. }
  461.  
  462.  
  463. Boolean TSimpliFace2::HandleKeyDown(AEDesc *target, EventRecord& theEvent)
  464. {
  465.     Boolean        wasHandled = false;
  466.     char         key = (char) (fTheEvent.message & charCodeMask);
  467.     
  468.     if ((fTheEvent.modifiers & cmdKey) && (fTheEvent.what == keyDown))
  469.     {
  470.         // only do command keys if we are not autokeying
  471.         AdjustMenus();                    // make sure menus are up to date
  472.         long mResult = MenuKey(key);
  473.         if (mResult != 0)                // if it wasn't a menu key, pass it through
  474.             wasHandled = HandleMenuCommand(target, HiWord(mResult), LoWord(mResult));
  475.     }
  476.     else
  477.     {
  478.         OSErr                err = 0;
  479.         AppleEvent            event, reply;
  480.         ProcessSerialNumber    aSelfPSN = gSelfPSN;
  481.         CStr255                theKeyPressed;
  482.         theKeyPressed[1] = key;
  483.         theKeyPressed[0] = 1;
  484.         CStr255                aeOtherParams =    "'PEVK':'EKEY',"
  485.                                             "'data':“" + theKeyPressed + "”";
  486.         err = AEBuildAppleEvent(kSignature, kAESystemEvent,
  487.                                 typeProcessSerialNumber, &aSelfPSN,
  488.                                 sizeof(aSelfPSN), kAutoGenerateReturnID,
  489.                                 kAnyTransactionID, &event,
  490.                                 (char*)aeOtherParams);
  491.         if (err == noErr)
  492.             err = AEPutParamDesc(&event, keyDirectObject, target);
  493.         
  494.         if (err == noErr)
  495.         {
  496.             err = AESend(&event, &reply, kAENoReply+kAEAlwaysInteract, 
  497.                              kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
  498.             AEDisposeDesc(&event);
  499.             wasHandled = (err == noErr);
  500.         }
  501.     }
  502.     
  503.     return wasHandled;
  504. }
  505.  
  506.  
  507. Boolean TSimpliFace2::HandleEvent(EventRecord& theEvent, Boolean& /*pass*/)
  508. {
  509.     Boolean        wasHandled = false;
  510.     AEDesc         target;
  511.     
  512.     InitAEDescs(&target, kEndOfList);
  513.  
  514.     switch (theEvent.what)
  515.     {
  516.         case mouseDown :
  517.             if (GetTargetObjectSpecifier(theEvent, &target) == noErr)
  518.                 wasHandled = HandleMouseDown(&target, theEvent);
  519.             break;
  520.         case keyDown :
  521.         case autoKey :
  522.             if (GetTargetObjectSpecifier(theEvent, &target) == noErr)
  523.                 wasHandled = HandleKeyDown(&target, theEvent);
  524.             break;
  525.     } // end switch (fTheEvent.what)
  526.  
  527.     DisposeAEDescs(&target, kEndOfList);
  528.     
  529.     return wasHandled;
  530. }
  531.  
  532.  
  533. OSErr TSimpliFace2::CollectAETEs(short /*languageCode*/, AEDesc& resultDesc)
  534. {
  535.     OSErr        err = noErr;
  536.     Handle        aeutH = NULL;
  537.     
  538.     aeutH = GetResource(typeAETE, 0);
  539.     if (aeutH)
  540.     {
  541.         char hState = HGetState(aeutH);
  542.         HLock(aeutH);
  543.         err = AEPutPtr(&resultDesc, 0, typeAETE, *aeutH, GetHandleSize(aeutH));
  544.         HSetState(aeutH, hState);
  545.     }
  546.     else
  547.         err = -192; /* resNotFound */ 
  548.  
  549.     return err;
  550. }
  551.  
  552.  
  553. /**********************************************************************
  554. ** PUBLIC AdjustMenus
  555. ***********************************************************************/
  556.  
  557. // Enable and disable menus based on the current state. The
  558. // user can only select enabled menu items. We set up all the
  559. // menu items before calling MenuSelect or MenuKey, since
  560. // these are the only times that a menu item can be selected.
  561. // Note that MenuSelect is also the only time the user will
  562. // see menu items. This approach to deciding what enable/
  563. // disable state a menu item has the advantage of
  564. // concentrating all the decision-making in one routine, as
  565. // opposed to being spread throughout the application. Other
  566. // application designs may take a different approach that may
  567. // or may not be as valid. 
  568.  
  569. void ExactAppend(MenuHandle aMenu, Str255 aString)
  570. {
  571.     unsigned char fillString[128];
  572.     /* Since AppendMenu will interpret meta-characters, first append a menu item with    */
  573.     /* no meta-characters, but which has the same length as aString, then set the menu    */
  574.     /* item to astring (SetItem doesn't interpret meta-characters). */
  575.     fillString[0] = aString[0];
  576.     if (aString[0])
  577.         memset(fillString + 1, 'a', aString[0]);
  578.     AppendMenu(aMenu, fillString);
  579.     SetItem(aMenu, CountMItems(aMenu), aString);
  580. }    
  581.     
  582. void TSimpliFace2::AdjustMenus(void)
  583. {
  584.     WindowPtr    frontmost;
  585.     MenuHandle    menu;
  586.     Boolean        undo;
  587.     Boolean        cutCopyClear;
  588.     Boolean        paste;
  589.  
  590.     frontmost = FrontWindow();
  591.  
  592.     /* Edit menu */
  593.  
  594.     menu = GetMHandle(mEdit);
  595.     undo = false;
  596.     cutCopyClear = false;
  597.     paste = false;
  598.     if (frontmost != NULL) {
  599.         undo = true;                // all editing is enabled for DA windows 
  600.         cutCopyClear = true;
  601.         paste = true;
  602.     }
  603.  
  604.     if (undo)
  605.         EnableItem(menu, iUndo);
  606.     else
  607.         DisableItem(menu, iUndo);
  608.  
  609.     if (cutCopyClear) {
  610.         EnableItem(menu, iCut);
  611.         EnableItem(menu, iCopy);
  612.         EnableItem(menu, iClear);
  613.     } 
  614.     else {
  615.         DisableItem(menu, iCut);
  616.         DisableItem(menu, iCopy);
  617.         DisableItem(menu, iClear);
  618.     }
  619.     if (paste)
  620.         EnableItem(menu, iPaste);
  621.     else
  622.         DisableItem(menu, iPaste);
  623.  
  624.     /* File Menu */
  625.  
  626.     menu = GetMHandle(mFile);
  627.     if (fWindowObjects.CountElements() > 0)
  628.         EnableItem(menu, iClose);
  629.     else
  630.         DisableItem(menu, iClose);
  631.     EnableItem(menu,iQuit);
  632. }
  633.  
  634. /**********************************************************************
  635. ** PUBLIC AdjustCursor
  636. ***********************************************************************/
  637.  
  638. void TSimpliFace2::AdjustCursor()
  639. {
  640.     Boolean        handled = false;
  641.         
  642.     if (!handled)
  643.         SetCursor(&fqd->arrow);
  644. }
  645.  
  646. /**********************************************************************
  647. ** PUBLIC DoMenuCommand
  648. ***********************************************************************/
  649.  
  650. // This is called when an item is chosen from the menu bar (after calling
  651. // MenuSelect or MenuKey). It does the right thing for each command.
  652.  
  653. void TSimpliFace2::DoMenuCommand(short menuID, short menuItem)
  654. {
  655.     short        itemHit;
  656.     Str255        daName;
  657.     short        daRefNum;
  658.     WindowPtr    window;
  659.  
  660.     window = FrontWindow();
  661.     switch (menuID) {
  662.         case mApple:
  663.             switch (menuItem) {
  664.                 case iAbout:        // bring up alert for About 
  665.                     itemHit = Alert(rAboutAlert, NULL);
  666.                     break;
  667.                 default:            // all non-About items in this menu are DAs et al 
  668.                     GetItem(GetMHandle(mApple), menuItem, daName);
  669.                     daRefNum = OpenDeskAcc(daName);
  670.                     break;
  671.             }
  672.             break;
  673.  
  674.         case mFile:
  675.             switch (menuItem) {
  676.                 case iQuit:
  677.                     Terminate();
  678.                     break;
  679.                 case iClose:
  680.                     TWindowObj *theWindObj = (TWindowObj*)(((WindowPeek)fWhichWindow)->refCon);
  681.                     if (theWindObj)
  682.                         theWindObj->CloseObject();
  683.                     else
  684.                         CloseDeskAcc(((WindowPeek) fWhichWindow)->windowKind);
  685.                     break;
  686.             }
  687.             break;
  688.  
  689.         case mEdit:                    // call SystemEdit for DA editing & MultiFinder 
  690.             if (!SystemEdit(menuItem-1))
  691.                 DebugStr((ConstStr255Param)"\pOops.  SystemEdit returned false.");
  692.             break;
  693.         
  694.     }
  695.     HiliteMenu(0);                    // unhighlight what MenuSelect (or MenuKey) hilited 
  696. }
  697.  
  698.  
  699.  
  700. void TSimpliFace2::GetThisAppName(CStr255& /*appName*/)
  701. {
  702.     //GetCurrAppName(appName);
  703.  
  704.  
  705. /**********************************************************************
  706. ** PUBLIC Terminate
  707. ***********************************************************************/
  708.  
  709. // Clean up the application and exits. You might want to close all
  710. // of your documents (and ask the user to save them) here.
  711.  
  712. void TSimpliFace2::Terminate(void)
  713. {
  714.     ExitLoop();
  715. } // Terminate
  716.  
  717.  
  718. /**********************************************************************
  719. ** PUBLIC StackNeeded/HeapNeeded
  720. ***********************************************************************/
  721.  
  722. long TSimpliFace2::StackNeeded()
  723. {
  724.     return kMinStackSize;
  725. }
  726.  
  727. long TSimpliFace2::HeapNeeded()
  728. {
  729.     return kMinHeapSize;
  730. }
  731.  
  732.  
  733. /**********************************************************************
  734. ** PUBLIC DoGoAway
  735. ***********************************************************************/
  736.  
  737. void TSimpliFace2::DoGoAway(void)
  738. {
  739.     TWindowObj *theWindObj = (TWindowObj*)(((WindowPeek)fWhichWindow)->refCon);
  740.     if (theWindObj)
  741.     {
  742.         if (TrackGoAway(fWhichWindow, fTheEvent.where)) 
  743.             theWindObj->CloseObject();
  744.     }
  745.     else
  746.         TApplication::DoGoAway();
  747. }
  748.  
  749. /**********************************************************************
  750. ** PUBLIC DoActivateEvt/DoUpdateEvt
  751. ***********************************************************************/
  752.  
  753. void TSimpliFace2::DoActivateEvt(void)
  754. {
  755.     // event record contains window ptr
  756.     fWhichWindow = (WindowPtr) fTheEvent.message;
  757.     SetPort(fWhichWindow);
  758.     
  759.     TWindowObj *theWindObj = (TWindowObj*)(((WindowPeek)fWhichWindow)->refCon);
  760.     if (theWindObj)
  761.         theWindObj->ActivateWindow((fTheEvent.modifiers & activeFlag) != 0);
  762. }
  763.  
  764. void TSimpliFace2::DoUpdateEvt(void)
  765. {
  766.     // event record contains window ptr
  767.     fWhichWindow = (WindowPtr) fTheEvent.message;
  768.     SetPort(fWhichWindow);
  769.     
  770.     TWindowObj *theWindObj = (TWindowObj*)(((WindowPeek)fWhichWindow)->refCon);
  771.     if (theWindObj)
  772.         theWindObj->UpdateWindow();
  773. }
  774.  
  775. /**********************************************************************
  776. ** PUBLIC AE Object Model support
  777. ***********************************************************************/
  778.  
  779.  
  780. OSErr TSimpliFace2::CountElements(DescType desiredClass, long *result)
  781. {
  782.     OSErr             err = errAEEventNotHandled;
  783.  
  784.     if (desiredClass == cWindow)
  785.     {
  786.         *result = fWindowObjects.CountElements();
  787.         err = 0;
  788.     }    
  789.     return err;
  790. }
  791.  
  792.                                     
  793. OSErr TSimpliFace2::GetProperty  (DescType propertyID, DescType wantType, AEDesc *result)
  794. {
  795.     OSAError     err = errAEEventNotHandled;
  796.     CStr255     theName;
  797.     
  798.     switch (propertyID)
  799.     {
  800.     case pName:
  801.         GetCurrAppName(theName);
  802.         err = AECreateDesc(typeChar, (Ptr)&theName[1], theName.Length(), result);
  803.         break;
  804.     case pVersion:
  805.         theName = kVersion;
  806.         err = AECreateDesc(typeChar, (Ptr)&theName[1], theName.Length(), result);
  807.         break;
  808.     case pIsFrontProcess:
  809.         Boolean theBoolean = false;
  810.         ProcessSerialNumber PSN1, PSN2;
  811.         err = GetFrontProcess(&PSN1);
  812.         if (err == noErr)
  813.             err = GetCurrentProcess(&PSN2);
  814.         if (err == noErr)
  815.             err = SameProcess(&PSN1, &PSN2, &theBoolean);
  816.         if (err == noErr)
  817.             err = AECreateDesc(typeBoolean, (Ptr)&theBoolean,
  818.                                 sizeof(theBoolean), result);
  819.         break;
  820.     case pSharedScript:
  821.         OSAID    tempID = gScriptAdministrator->GetSharedScript();
  822.         if (tempID != kOSANullScript)
  823.         {
  824.         printf("TSimpliFace2::GetProperty(): get shared script as type '%.4s'\n",
  825.                 (char*)&wantType);
  826.         if (wantType == typeChar || wantType == typeIntlText)
  827.             {    // if caller wants text, we need to de-compile the script
  828.                 err = (OSErr)OSAGetSource(gScriptingComponent, tempID, 
  829.                                             wantType, result);
  830.             }
  831.             else
  832.             {
  833.                 if (wantType == typeWildCard)
  834.                     wantType = typeOSAGenericStorage;
  835.                     
  836.                 err = (OSErr)OSAStore(gScriptingComponent, tempID, 
  837.                                     wantType, kOSAModeDontStoreParent, result);
  838.             }
  839.         }
  840.         break;
  841.     default:
  842.         err = TScriptableObject::GetProperty(propertyID, wantType, result);
  843.         break;
  844.     }
  845.  
  846.     return err;
  847. }
  848.  
  849.  
  850. OSErr TSimpliFace2::SetProperty  (DescType propertyID, const AEDesc *theData)
  851. {
  852.     OSAError        err = errAEEventNotHandled;
  853.  
  854.     switch (propertyID)
  855.     {
  856.     case pSharedScript:
  857.         OSAID theValueID = kOSANullScript;
  858.         if (theData->descriptorType == typeChar
  859.             || theData->descriptorType == typeIntlText)
  860.             err = OSACompile(gScriptingComponent, theData, 
  861.                              kOSAModeCompileIntoContext, &theValueID);
  862.         else // it it's not text, we assume the script is already compiled
  863.         {
  864.             err = OSALoad(gScriptingComponent, theData, 
  865.                             kOSAModeNull, &theValueID);
  866.             // the following section strips any existing parent script:
  867.             // (it did not exist in version 1 of SimpliFace)
  868.             if (err == noErr) 
  869.             { 
  870.                 AEDesc        newData;
  871.                 err = OSAStore(gScriptingComponent, theValueID, 
  872.                                     typeOSAGenericStorage, 
  873.                                     kOSAModeDontStoreParent, 
  874.                                     &newData);
  875.                 if (err == noErr) 
  876.                 {
  877.                     OSADispose(gScriptingComponent, theValueID);
  878.                     theValueID = kOSANullScript;
  879.                     err = (OSErr)OSALoad(gScriptingComponent, &newData, 
  880.                                                 kOSAModeNull, &theValueID);
  881.                     AEDisposeDesc(&newData);
  882.                 }
  883.             }
  884.         }
  885.         if (err == noErr)
  886.             gScriptAdministrator->SetSharedScript(theValueID);
  887.         break;
  888.     default:
  889.         err = TScriptableObject::SetProperty(propertyID, theData);
  890.         break;
  891.     }
  892.     
  893.     return (OSErr)err;
  894. }    
  895.  
  896.  
  897. OSErr TSimpliFace2::CreateNewElement    (DescType desiredClass,
  898.                                         DescType position,
  899.                                         AEDesc *theData,
  900.                                         AERecord *theProperties,
  901.                                         TScriptableObject *theContainerObj,
  902.                                         TScriptableObject **theNewObj)
  903. {
  904.     OSErr             err = errAEEventNotHandled;
  905.     
  906.     if (desiredClass == cWindow)
  907.     {
  908.         TWindowObj    *newWindowObj = NULL;
  909.         
  910.         if (theProperties)
  911.             newWindowObj = new TWindowObj(NULL, theProperties);
  912.         else
  913.         {
  914.             newWindowObj = new TWindowObj(NULL);
  915.             if (newWindowObj && theData)
  916.                 newWindowObj->SetProperty(pName, theData);
  917.         }
  918.         if (newWindowObj)
  919.         {
  920.             fWindowObjects.InsertElement((long)newWindowObj);
  921.             *theNewObj = newWindowObj;
  922.             err = 0;
  923.         }
  924.     }
  925.  
  926.     return err;
  927. }    
  928.  
  929.  
  930. OSErr TSimpliFace2::ResolveContainer(TScriptableObject **theContainerObj)
  931. {
  932.     OSErr             err = 0;
  933.     
  934.     *theContainerObj = NULL;
  935.  
  936.     return err;
  937. }
  938.  
  939.                                     
  940. OSErr TSimpliFace2::ResolveElementByName(DescType desiredClass,
  941.                                         CStr255& nameStr,
  942.                                         TScriptableObject **theResultObj)
  943. {
  944.     OSErr       err = errAEEventNotHandled;
  945.     WindowPtr    theWindow = NULL;
  946.     
  947.     theWindow = WindowNameToWindowPtr((StringPtr)nameStr);
  948.     if (theWindow)
  949.     {    
  950.         // we are making a possibly dangerous assumption: that all windows are ours!
  951.         *theResultObj = (TScriptableObject*)(((WindowPeek)theWindow)->refCon);
  952.         if (*theResultObj != NULL)
  953.             err = 0;
  954.     }
  955.     else
  956.     {
  957.         TWindowObj    *aWindowObj = NULL;
  958.         long        numWindows = fWindowObjects.CountElements();
  959.         CStr255     aName;
  960.         
  961.         while (numWindows > 0)
  962.         {
  963.             aWindowObj = (TWindowObj*)(fWindowObjects.GetElement(numWindows));
  964.             if (aWindowObj)
  965.             {
  966.                 aWindowObj->GetName(aName);
  967.                 if (aName == nameStr)
  968.                 {
  969.                     *theResultObj = aWindowObj;
  970.                     numWindows = 0;
  971.                     err = 0;
  972.                 }
  973.             }
  974.             numWindows--;
  975.         }
  976.     }
  977.     
  978.     return err;
  979. }
  980.  
  981.                                     
  982. OSErr TSimpliFace2::ResolveElementByIndex(DescType desiredClass,
  983.                                         short theIndex,
  984.                                         TScriptableObject **theResultObj)
  985. {
  986.     OSErr       err = errAEEventNotHandled;
  987.     WindowPtr    theWindow = NULL;
  988.     CStr255     nameStr = "";
  989.     short        index = theIndex;
  990.     
  991.     if (index<0)
  992.         index = CountWindows()+index+1;
  993.         
  994.     theWindow = GetWindowPtrOfNthWindow(index);
  995.     if (theWindow)
  996.     {    
  997.         // we are making a possibly dangerous assumption: that all windows are ours!
  998.         *theResultObj = (TScriptableObject*)(((WindowPeek)theWindow)->refCon);
  999.         if (*theResultObj != NULL)
  1000.             err = 0;
  1001.     }
  1002.     
  1003.     return err;
  1004. }
  1005.  
  1006.  
  1007.  
  1008.  
  1009. OSErr TSimpliFace2::GetTargetObjectSpecifier  (EventRecord& theEvent, AEDesc *result)
  1010. {
  1011.     WindowPtr    theWindow = FrontWindow();
  1012.     
  1013.     if (theEvent.what == mouseDown)
  1014.         FindWindow(theEvent.where, &theWindow);
  1015.             
  1016.     if (theWindow)
  1017.     {    
  1018.         SetPort(theWindow);
  1019.         // we are making a possibly dangerous assumption: that all windows are ours!
  1020.         TWindowObj    *aWindowObj = (TWindowObj*)(((WindowPeek)theWindow)->refCon);
  1021.         if (aWindowObj)
  1022.             return aWindowObj->GetTargetObjectSpecifier(theEvent, result);
  1023.     }
  1024.     else
  1025.     {
  1026.         OSErr         err = 0;
  1027.         AEDesc        containerDesc, newContainerDesc;
  1028.         
  1029.         err = MakeNullDesc(&containerDesc);
  1030.         
  1031.         if (err == noErr)
  1032.         {
  1033.             CStr255        progName;
  1034.             AEDesc        nameDesc;
  1035.             
  1036.             GetCurrAppName(progName);
  1037.             err = MakeNameDesc(progName, &nameDesc);
  1038.             if (err == noErr)
  1039.             {
  1040.                 err = CreateObjSpecifier(cApplication, &containerDesc, formName, 
  1041.                                          &nameDesc, true, &newContainerDesc);
  1042.                 containerDesc = newContainerDesc;
  1043.             }
  1044.         }
  1045.         *result = containerDesc;
  1046.         return err;
  1047.     }
  1048. }    
  1049.  
  1050.  
  1051. void TSimpliFace2::FixUpScriptReferences(TScriptableObject* theParent)
  1052. {
  1053.     // first call inherited routine in case old script is our parent
  1054.     TScriptableObject::FixUpScriptReferences(theParent);
  1055.  
  1056.     // next, fix up references for any contained objects...
  1057.     TWindowObj    *aWindowObj = NULL;
  1058.     long        numWindows = fWindowObjects.CountElements();
  1059.     
  1060.     while (numWindows > 0)
  1061.     {
  1062.         aWindowObj = (TWindowObj*)(fWindowObjects.GetElement(numWindows));
  1063.         if (aWindowObj)
  1064.             aWindowObj->FixUpScriptReferences(theParent);
  1065.         numWindows--;
  1066.     }
  1067. }
  1068.  
  1069.  
  1070.